package org.example.video.service;

import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.http.Method;
import org.apache.commons.io.FilenameUtils;
import org.example.video.dao.VideoRepository;
import org.example.video.pojo.PageResult;
import org.example.video.pojo.Video;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.server.ResponseStatusException;

import java.io.InputStream;
import java.util.UUID;

@Service
public class VideoService {

    private final MinioClient minioClient;
    private final VideoRepository videoRepo;

    @Value("${video.bucket.raw}")
    private String rawBucket;
    @Value("${video.prefix.raw}")
    private String rawPrefix;
    @Value("${video.bucket.hls}")
    private String hlsBucket;

    public VideoService(MinioClient minioClient, VideoRepository videoRepo) {
        this.minioClient = minioClient;
        this.videoRepo = videoRepo;
    }

    public Video upload(MultipartFile file, String title, String desc) throws Exception {
        UUID videoId = UUID.randomUUID();
        String ext = FilenameUtils.getExtension(file.getOriginalFilename());
        String objectRaw = rawPrefix + "/" + videoId + "." + ext;

        try (InputStream inputStream = file.getInputStream()) {
            PutObjectArgs build = PutObjectArgs.builder()
                    .bucket(rawBucket)
                    .object(objectRaw)
                    .stream(inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build();
            minioClient.putObject(build);
        } finally {
            // 确保文件被删除
            try {
                file.getResource().getFile().delete();
            } catch (Exception e) {
                // 忽略删除失败的错误
            }
        }

        Video video = new Video();
        video.setId(videoId);
        video.setTitle(title);
        video.setDescription(desc);
        video.setBucketRaw(rawBucket);
        video.setObjectRaw(objectRaw);
        video.setStatus(Video.Status.PENDING);
        return videoRepo.save(video);
    }

    public String getPlayUrl(UUID id) throws Exception {
        Video video = videoRepo.findById(id)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));

        GetPresignedObjectUrlArgs build = GetPresignedObjectUrlArgs.builder()
                .method(Method.GET)
                .bucket(hlsBucket)
                .object(video.getPlaylistKey())
                .expiry(3600)
                .build();

        // 1 小时过期
        return minioClient.getPresignedObjectUrl(build);
    }

    public PageResult<Video> getVideos(String title, Integer page, Integer size) {
        // 创建分页请求，按创建时间倒序排序
        Pageable pageRequest = PageRequest.of(page - 1, size, Sort.by("id").descending());
        // 执行分页查询并转换为自定义分页对象
        Page<Video> videoPage = videoRepo.findByTitleContaining(title, pageRequest);
        return PageResult.of(videoPage);
    }
}